package com.chenwenxuan.sync.console.accessor;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import com.chenwenxuan.sync.console.accessor.filter.AccessorFilter;
import com.chenwenxuan.sync.utils.Path;
import com.chenwenxuan.sync.utils.SyncFile;

public class LocalFileAccessor extends CommonAccessor {

	private IOException inner;
	
	@Override
	public void connect() throws IOException {}

	@Override
	public void disconnect() throws IOException {}

	@Override
	public SyncFile getFileProperty(Path fullPath) throws IOException {
		
		File f = new File(fullPath.toPortableString());
		long lastModified = 0;
		long fileSize = 0;
		
		if ( f.exists() ) {
			lastModified = f.lastModified();
			fileSize = f.length();
		} 
		return new SyncFile(fullPath, lastModified, fileSize, f, f.exists(), f.isDirectory());
	}

	@Override
	public void ls(Path source, final AccessorFilter filter) throws IOException {
		File sourceFolder = new File(source.toPortableString());
		
		if ( !sourceFolder.exists() ) {
			throw new FileNotFoundException("Can not find " + sourceFolder.getAbsolutePath() );
		}
		
		inner = null;
		
		sourceFolder.listFiles(new FilenameFilter() {

			@Override
			public boolean accept(File dir, String name) {
				
				if ( inner != null ) return false;
				
				Path path = new Path(dir.getAbsolutePath());
				Path filePath = path.append(name);
				SyncFile sf;
				try {
					sf = getFileProperty(filePath);
				} catch (IOException e) {
					inner = e;
					return false;
				}
				
				return filter.accept(filePath, sf);
			}

		});
		
		throwIOEandClean();

	}
	
	protected void throwIOEandClean() throws IOException {
		IOException thrown = inner;
		inner = null;
		throw thrown;
	}

	@Override
	public boolean mkdir(Path fullDirPath) throws IOException {
		return new File(fullDirPath.toPortableString()).mkdirs();
	}

	@Override
	public boolean deleteFile(Path fullFilePath) throws IOException {
		File f = new File(fullFilePath.toPortableString());
		
		if ( !f.exists() )
			return true;
		
		return f.delete();
	}

	@Override
	public boolean deleteFolder(Path fullFolderPath) throws IOException {
		File f = new File(fullFolderPath.toPortableString());
		if ( !f.exists() )	
			return true;
		return f.delete();
	}

	@Override
	public void setLastModified(Path fullPath, long lastModified) {
		File f = new File(fullPath.toPortableString());
		f.setLastModified(lastModified);
	}

	@Override
	public InputStream openInputStream(Path filePath) throws IOException {
		return new FileInputStream(filePath.toPortableString());
	}

	@Override
	public OutputStream openOutputStream(Path filePath) throws IOException {
		return new FileOutputStream(filePath.toPortableString());
	}

}
